package com.gzm.check.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.PropDesc;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gzm.check.entity.LisTestReport;
import com.gzm.check.entity.UrineRoutine;
import com.gzm.check.entity.UrineRoutineValue;
import com.gzm.check.mapper.UrineRoutineMapper;
import com.gzm.check.mapper.UrineRoutineValueMapper;
import com.gzm.check.service.IUrineRoutineService;
import com.gzm.check.utils.UrineRoutEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 尿常规表 服务实现类
 * </p>
 *
 * @author gzm
 * @since 2021-01-21
 */
@Service
@DS("db2")
public class UrineRoutineServiceImpl extends ServiceImpl<UrineRoutineMapper, UrineRoutine> implements IUrineRoutineService {
    @Resource
    private UrineRoutineMapper urineRoutineMapper;
    @Resource
    private UrineRoutineValueMapper urineRoutineValueMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void urineRoutineConver(LisTestReport lisTestReport) throws InvocationTargetException, IllegalAccessException {
        // 获取尿常规
        List<UrineRoutine> urineRoutines = urineRoutineMapper.selectList(Wrappers.lambdaQuery(UrineRoutine.class)
                .eq(UrineRoutine::getHealthid, lisTestReport.getPatientsIndex()).apply("date_format(report_date,'%Y-%m-%d') = date_format({0},'%Y-%m-%d')", lisTestReport.getVisitDate()));

        // 为空,此检查数据第一次读取,需要新建
        UrineRoutine urineRoutine;
        boolean save = false;
        if (IterUtil.isEmpty(urineRoutines)) {
            urineRoutine = new UrineRoutine();
            urineRoutine.setName(lisTestReport.getPatientsName());
            urineRoutine.setInstitutionCode(lisTestReport.getInstitutionCode());
            urineRoutine.setInstitutionName(lisTestReport.getInstitutionName());
            urineRoutine.setHealthid(lisTestReport.getPatientsIndex());
            urineRoutine.setGender(Convert.toInt(lisTestReport.getSexCode(), 9));
            urineRoutine.setCheckDate(LocalDateTimeUtil.of(lisTestReport.getVisitDate()));
            urineRoutine.setReportDate(LocalDateTimeUtil.of(lisTestReport.getReportDate()));
            // 查询对应关系
            LambdaQueryWrapper<UrineRoutineValue> wrapper = Wrappers.lambdaQuery(UrineRoutineValue.class);
            wrapper.eq(UrineRoutineValue::getInsId, lisTestReport.getInstitutionCode());
            wrapper.orderByDesc(UrineRoutineValue::getCreateDate);
            wrapper.last("limit 1");
            UrineRoutineValue urineRoutineValue = urineRoutineValueMapper.selectOne(wrapper);
            if (urineRoutineValue == null) {
                urineRoutineValue = new UrineRoutineValue();
                urineRoutineValue.setInsId(lisTestReport.getInstitutionCode());
                urineRoutineValue.setCreateDate(LocalDateTime.now());
                urineRoutineValueMapper.insert(urineRoutineValue);
            }
            urineRoutine.setConsultid(urineRoutineValue.getId());
            save = true;
        } else {
            urineRoutine = urineRoutines.get(0);
        }

        // 修改检查数据
        final Collection<PropDesc> propDescs = BeanUtil.getBeanDesc(urineRoutine.getClass()).getProps();

        String fieldName = UrineRoutEnum.getFieldName(lisTestReport.getItemdetailCode());
        String fieldNameUnit = UrineRoutEnum.getFieldNameUnit(lisTestReport.getItemdetailCode());
        // 未在枚举中找到对应值,无法用反射为之赋值
        if (StrUtil.isBlank(fieldName)) {
            return;
        }

        int ct = 0;
        // 赋值结果
        for (PropDesc propDesc : propDescs) {
            if (StrUtil.equals(fieldName, propDesc.getFieldName())) {
                Method setter = propDesc.getSetter();
                setter.invoke(urineRoutine, lisTestReport.getConclusion());
                ct++;
            }
            if (StrUtil.equals(fieldNameUnit, propDesc.getFieldName())) {
                Method setter = propDesc.getSetter();
                setter.invoke(urineRoutine, lisTestReport.getResultUnit());
                ct++;
            }
            if (ct == 2) {
                break;
            }
        }

        // 判断范围值
        UrineRoutineValue urineRoutineValue = urineRoutineValueMapper.selectById(urineRoutine.getConsultid());
        Collection<PropDesc> props = BeanUtil.getBeanDesc(urineRoutineValue.getClass()).getProps();
        String upper = UrineRoutEnum.getUpper(lisTestReport.getItemdetailCode());
        String lower = UrineRoutEnum.getLower(lisTestReport.getItemdetailCode());

        String upperVal = null;
        String lowerVal = null;

        PropDesc pu = null;
        PropDesc pl = null;

        int count = 0;

        for (PropDesc prop : props) {
            if (StrUtil.equals(upper, prop.getFieldName())) {
                pu = prop;
                Method getter = prop.getGetter();
                upperVal = Convert.toStr(getter.invoke(urineRoutineValue));
                count++;
            }
            if (StrUtil.equals(lower, prop.getFieldName())) {
                pl = prop;
                Method getter = prop.getGetter();
                lowerVal = Convert.toStr(getter.invoke(urineRoutineValue));
                count++;
            }
            if (count == 2) {
                break;
            }
        }

        String referenceUpper = lisTestReport.getReferenceUpper();
        String referenceLower = lisTestReport.getReferenceLower();

        // 范围值为null需要赋值
        if (StrUtil.isBlank(upperVal) && pu != null) {
            Method setter = pu.getSetter();
            setter.invoke(urineRoutineValue, referenceUpper);
            upperVal = referenceUpper;
        }
        // 范围值为null需要赋值
        if (StrUtil.isBlank(lowerVal) && pl != null) {
            Method setter = pl.getSetter();
            setter.invoke(urineRoutineValue, referenceLower);
            lowerVal = referenceLower;
        }

        boolean sign = false;
        if (!StrUtil.equals(upperVal, referenceUpper) || !StrUtil.equals(lowerVal, referenceLower)) {
            Method sett = pu.getSetter();
            sett.invoke(urineRoutineValue, referenceUpper);
            Method setter = pl.getSetter();
            setter.invoke(urineRoutineValue, referenceLower);
            sign = true;
        }

        // 范围值没有被对应,需要新建范围值
        if (sign) {
            urineRoutineValue.setId(null);
            urineRoutineValue.setCreateDate(LocalDateTime.now());
            urineRoutineValueMapper.insert(urineRoutineValue);
            urineRoutine.setConsultid(urineRoutineValue.getId());
        } else {
            urineRoutineValueMapper.updateById(urineRoutineValue);
        }

        // 没有记录需要新建检查记录数据
        if (save) {
            urineRoutineMapper.insert(urineRoutine);
        } else {
            urineRoutineMapper.updateById(urineRoutine);
        }

    }
}
